#!/usr/bin/python3
"""
@groupname: actually_is_dolan
@authors: Lauge Groes, Florian Biermann {lgro, fbie}@itu.dk

It is, though, faster to run the code with an
implementation < 3.0, as i/o in Python 3 seems
to be more high-level.
"""

class Person:
    def __init__(self, pid, prefs):
        self.id = pid
        self.prefs = prefs
        
class Man(Person):
    def get_next_pref(self):
        if len(self.prefs) > 0:
            return self.prefs.pop(0)
        return None

class Woman(Person):
    def get_pref(self, pid):
        return self.prefs[pid]
    
def stable_matching(men, women):
    
    matches = {k:None for k in women.keys()}
    all_men = {man.id:man for man in men}
    
    while len(men) > 0 and len(men[0].prefs) > 0:
        man = men.pop(0)
        woman = women[man.get_next_pref()]
        
        if not matches[woman.id]:
            matches[woman.id] = man.id
        else:
            if woman.get_pref(man.id) < woman.get_pref(matches[woman.id]):
                rejected = all_men[matches[woman.id]]
                men.append(rejected)
                matches[woman.id] = man.id
            else:
                men.append(man)
    
    return matches

if __name__ == "__main__":
    import sys, time
        
    def parse_name(l):
        contents = l.split(" ")
        return (int(contents[0]), contents[1].rstrip())
    
    def parse_preference(l):
        pid = int(l.split(": ")[0])
        prefs = [int(i) for i in l.rstrip().split(" ")[1:]]
        return (pid, prefs)
    
    def transform_women_pref(pref):
        pref_map = dict()
        for i in range(len(pref)):
            pref_map[pref[i]] = i
        return pref_map
    
    for f in sys.argv[1:]:        
        mode = True
        names = dict()
        men = list()
        women = dict()
           
        t_start = time.time()
        with open(f, "r") as inp:
            for line in inp:                
                if line.startswith("#"):
                    pass
                
                elif line in ("",  " ", "\n"):
                    mode = False
                
                elif mode:
                    if not line.startswith("n"):
                        name = parse_name(line)
                        names[name[0]] = name[1]

                else:
                    pref = parse_preference(line)
                    if pref[0] % 2 == 0:
                        w = Woman(pref[0], transform_women_pref(pref[1]))
                        women[w.id] = w
                    else:
                        men.append(Man(pref[0], pref[1]))
                        
        print("%s: " %f)
        result = stable_matching(men, women)
        t_end = time.time() - t_start
        result_list = [i for i in result.items()]
        result_list.sort(key=lambda x: x[1])
        for k, i in result_list:
            print("%s -- %s" %(names[i], names[k]))
        print("Took %f seconds" %t_end)
